/*
 * ethernet.h
 *
 *  Created on: 13/06/2011
 *      Author: george
 */

#ifndef ETHERNET_PROCESS_H_
#define ETHERNET_PROCESS_H_


#include <string>

#include <net/ethernet.h>
#include <pcap.h>
#include "defines.h"
#include "errors.h"
using namespace std;


typedef struct ether_header ether_header_t;
typedef struct pcap_pkthdr pcap_pkthdr_t;
typedef struct ip ip_t;

	class NoEthernetHeader: public exception{
		virtual const char *what(){
			return "Cabecalho ethernet inválido ou cabeçalho corrompido";
		}
	};

class EthernetProcessor {
public:
	unsigned int rlen;
	struct pcap_pkthdr *h;
	u_char * p;
	ether_header_t *eh;

	EthernetProcessor(){}

	EthernetProcessor(const struct pcap_pkthdr *h,const u_char *p){
		this->h = (struct pcap_pkthdr*)h;
		this->p = (u_char*)p;
		this->eh = (ether_header_t *)(this->p);

		if ( h->caplen < ETHERNET_SIZE ){
			throw new NoEthernetHeader;
		}
	}

	string ntoha(const u_char *addr){
		string saddr;
		char buff[2];

		for(int i=0; i < ETHER_ADDR_LEN; i++){
			if ( i == 0 ){
				sprintf(buff, "%02X", addr[i]);
			}else{
				sprintf(buff, ":%02X", addr[i]);
			}

			saddr += buff;
		}

		return saddr;
	}

	ip_t *getIp(){

		if ( h->caplen - sizeof(ether_header_t) < sizeof(ip_t) ){
			throw Err::NoEnoughData();
		}
		return (ip_t*)(this->p+sizeof(ether_header_t));
	}

	bool isIp(){
		return ntohs(this->eh->ether_type) == ETHERTYPE_IP;
	}

};

#endif /* ETHERNET_PROCESS_H_ */
